package com.nb.service.impl;

import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.nb.dto.*;
import com.nb.entity.SysRoleDeptEntity;
import com.nb.mapper.DeptMapper;
import com.nb.mapper.RoleMapper;
import com.nb.mapper.SysRoleAclMapper;
import com.nb.mapper.SysRoleDeptMapper;
import com.nb.service.AuthService;
import com.nb.service.RoleService;
import com.nb.vo.RoleVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.nb.entity.Role;
import com.nb.entity.SysRoleAcl;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;

@Service
public class RoleServiceImpl implements RoleService {

    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private DeptMapper deptMapper;
    @Autowired
    private AuthService authService;
    @Autowired
    private SysRoleAclMapper sysRoleAclMapper;
    @Autowired
    private SysRoleDeptMapper sysRoleDeptMapper;
    @Override
    public List<Role> list() {
        return roleMapper.selectAll();
    }

    @Override
    @Transactional
    public Long createRole(CreateRoleDTO dto) {
        // 检查角色编码唯一性
        if (!checkRoleCodeUnique(dto.getCode(), null)) {
            throw new RuntimeException("角色编码已存在");
        }

        Role role = new Role();
        BeanUtils.copyProperties(dto, role);
        role.setIsDelete(0);
        role.setCreatedBy("system");
        role.setCreatedTime(LocalDateTime.now());
        role.setUpdatedTime(LocalDateTime.now());

        roleMapper.insert(role);
        return role.getId();
    }

    @Override
    @Transactional
    public boolean updateRole(UpdateRoleDTO dto) {
        // 检查角色是否存在
        Role existRole = roleMapper.selectOneByQuery(QueryWrapper.create().eq("id", dto.getId()));
        if (existRole == null) {
            throw new RuntimeException("角色不存在");
        }

        // 检查角色编码唯一性
        if (!checkRoleCodeUnique(dto.getCode(), dto.getId())) {
            throw new RuntimeException("角色编码已存在");
        }

        Role role = new Role();
        BeanUtils.copyProperties(dto, role);
        role.setUpdatedTime(LocalDateTime.now());

        return roleMapper.update(role) > 0;
    }

    @Override
    @Transactional
    public boolean deleteRole(Long id) {
        // 先删除角色关联的权限
        QueryWrapper queryWrapper = QueryWrapper.create()
                .eq("role_id", id);
        sysRoleAclMapper.deleteByQuery(queryWrapper);

        // 再删除角色
        return roleMapper.deleteById(id) > 0;
    }

    @Override
    public Page<RoleVO> getRolePage(RoleQueryDTO queryDTO) {
        Page<Role> page = Page.of(queryDTO.getPageNum(), queryDTO.getPageSize());

        QueryWrapper queryWrapper = QueryWrapper.create();
        // 当名称不为空时，才添加模糊查询条件
        if (queryDTO.getName() != null) {
            queryWrapper.like("name", queryDTO.getName());
        }

// 当编码不为空时，才添加模糊查询条件
        if (queryDTO.getCode() != null) {
            queryWrapper.like("code", queryDTO.getCode());
        }
        // 按创建时间降序（使用Role实体的createdTime属性引用）
        queryWrapper.orderBy(Role::getCreatedTime, false);

        Page<Role> rolePage = roleMapper.paginate(page, queryWrapper);

        Page<RoleVO> resultPage = new Page<>(rolePage.getPageNumber(), rolePage.getPageSize());
        resultPage.setTotalRow(rolePage.getTotalRow());

        // 转换为VO并查询权限信息
        for (Role role : rolePage.getRecords()) {
            RoleVO vo = new RoleVO();
            BeanUtils.copyProperties(role, vo);
            List<Long> aclIdList = roleMapper.selectAclIdListByRoleId(role.getId());
            vo.setAclIdList(aclIdList);
            resultPage.getRecords().add(vo);
        }

        return resultPage;
    }

    @Override
    public RoleVO getRoleDetail(Long id) {
        Role role = roleMapper.selectOneByQuery(QueryWrapper.create().eq("id", id));
        if (role == null) {
            return null;
        }

        RoleVO vo = new RoleVO();
        BeanUtils.copyProperties(role, vo);
        List<Long> aclIdList = roleMapper.selectAclIdListByRoleId(id);
        vo.setAclIdList(aclIdList);

        return vo;
    }

    @Override
    @Transactional
    public boolean assignAcl(AssignAclDTO dto) {
        // 先删除原有权限关联
        QueryWrapper queryWrapper = QueryWrapper.create()
                .eq("role_id", dto.getRoleId());
        sysRoleAclMapper.deleteByQuery(queryWrapper);

        // 新增权限关联
        if (dto.getAclIdList() != null && !dto.getAclIdList().isEmpty()) {
            for (Long aclId : dto.getAclIdList()) {
                SysRoleAcl roleAcl = new SysRoleAcl();
                roleAcl.setRoleId(dto.getRoleId());
                roleAcl.setAclId(aclId);
                roleAcl.setCreatedTime(LocalDateTime.now());
                sysRoleAclMapper.insert(roleAcl);
            }
        }

        return true;
    }
    @Override
    @Transactional
    public boolean assignDataScope(AssignDataScopeDTO dto) {
        // 1. 校验角色存在性
        Role role = roleMapper.selectOneById(dto.getRoleId());
        if (role == null) {
            throw new RuntimeException("角色不存在");
        }

        // 2. 校验部门有效性
        if (dto.getDeptIds() != null && !dto.getDeptIds().isEmpty()) {
            for (Long deptId : dto.getDeptIds()) {
                com.nb.entity.Dept dept = deptMapper.selectOneById(deptId);
                if (dept == null) {
                    throw new RuntimeException("部门ID " + deptId + " 不存在");
                }
            }
        }

        // 3. 更新sys_role_dept
        // 先删除原有部门关联
        QueryWrapper queryWrapper = QueryWrapper.create()
                .eq("role_id", dto.getRoleId());
        sysRoleDeptMapper.deleteByQuery(queryWrapper);

        // 新增部门关联
        if (dto.getDeptIds() != null && !dto.getDeptIds().isEmpty()) {
            for (Long deptId : dto.getDeptIds()) {
                SysRoleDeptEntity roleDept = new SysRoleDeptEntity();
                roleDept.setRoleId(dto.getRoleId());
                roleDept.setDeptId(deptId);
                roleDept.setCreatedTime(new Date());
                sysRoleDeptMapper.insert(roleDept);
            }
        }

        // 4. 刷新用户权限缓存
        // 这里可以添加刷新用户权限缓存的逻辑
        // 由于权限变更可能影响多个用户，我们可以选择清除所有用户的权限缓存，
        // 或者只清除与该角色关联的用户的权限缓存
        System.out.println("角色数据权限已更新，需要刷新相关用户的权限缓存");

        return true;
    }

    @Override
    public boolean checkRoleCodeUnique(String code, Long id) {
        QueryWrapper queryWrapper = QueryWrapper.create()
                .eq("code", code);

        if (id != null) {
            queryWrapper.ne("id", id);
        }

        Role role = roleMapper.selectOneByQuery(queryWrapper);
        return role == null;
    }
}
